package io.renren.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWTExpiredException;
import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.JWTVerifyException;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import io.renren.config.FileServerConfig;
import io.renren.dao.ApplicationDao;
import io.renren.dao.MessageEntityDao;
import io.renren.dao.UserDao;
import io.renren.dao.UserInfoDao;
import io.renren.entity.Application;
import io.renren.entity.ChangePasswordModel;
import io.renren.entity.CheckCodeModel;
import io.renren.entity.MessageEntity;
import io.renren.entity.TokenGeneratorInputModel;
import io.renren.entity.TokenModel;
import io.renren.entity.UserExistModel;
import io.renren.entity.UserInfo;
import io.renren.entity.UserInfoModel;
import io.renren.entity.UserRegModel;
import io.renren.entity.VerifyCheckCodeInputModel;
import io.renren.po.User;
import io.renren.service.DataInfoQueryService;
import io.renren.service.UserService;
import io.renren.util.DigestUtil;
import io.renren.util.ExpiringMapUtil;
import io.renren.vo.RespModel;
import net.jodah.expiringmap.ExpiringMap;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("UserService")
public class UserServiceImpl implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserInfoDao userInfoDao;
    @Autowired
    private ApplicationDao applicationDao;
//	@Autowired
//	private StatsService statsService;

    @Autowired
    private FileServerConfig fileServerConfig;

    @Autowired
    private DataInfoQueryService dataInfoQueryService;
    @Autowired
    private MessageEntityDao messageEntityDao;

    /**
     * 注册一个用户
     *
     * @param userInput
     * @return
     */

    public RespModel<String> add(UserRegModel userInput) {
        if (userInput == null || StringUtils.isBlank(userInput.getUsername())
                || StringUtils.isBlank(userInput.getPassword())
                || StringUtils.isBlank(userInput.getApplicationId())
                || StringUtils.isBlank(userInput.getCheckcodeId())
                || StringUtils.isBlank(userInput.getCheckcode())) {
            RespModel<String> resp = new RespModel("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        // check check code is ok
        ExpiringMap<String, CheckCodeModel> map = ExpiringMapUtil.expiringMap;
        if (!map.containsKey(userInput.getCheckcodeId())) {
            RespModel<String> resp = new RespModel<String>("failed", "404", "CHECKCODE IS OUTDATED", null);
            return resp;
        }
        // 1.用户填写的验证码和验证码不符；2.发送验证码的号码和用户注册的手机号码不符
        if (!map.get(userInput.getCheckcodeId()).getCheckcode().equals(userInput.getCheckcode())) {
            RespModel<String> resp = new RespModel("failed", "403", "CHECKCODE IS WRONG", null);
            return resp;
        }
        if (!map.get(userInput.getCheckcodeId()).getId().equals(userInput.getUsername())) {
            return new RespModel<String>(
                    "failed",
                    "405",
                    "THE PHONE OF RECEVIE CHECKCODE IS DIFFERENT WITH USERNAME",
                    null);
        }
        User user = new User();
        user.setApplicationId(userInput.getApplicationId());
        user.setUsername(userInput.getUsername());
        user.setPassword(DigestUtil.md5(userInput.getPassword()));
//        user.setCreateDate();  创建user对象时已经赋值

        try {
            User u = userDao.findOne(userInput.getUsername());
            if (u != null) {
                RespModel<String> resp = new RespModel<String>("failed", "400",
                        "USER ALREADY EXIST", null);
                return resp;
            }
            //save user if user not exits
            userDao.insert(user);

            //ADD USERINFO
            UserInfo ui = userInput.getUserinfo();
            if (ui != null) {
                ui.setUsername(userInput.getUsername());
                ui.setApplicationId(userInput.getApplicationId());
                userInfoDao.insert(ui);
            }

            //add stats
//			statsService.addStats(new Stats(userInput.getApplicationId(),userInput.getUsername(), UserBehavior.REG.toString(),""));
            RespModel<String> resp = new RespModel<>("success", "", "USER REG SUCCESS",
                    null);
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(add user is fail):", e);
            RespModel<String> resp = new RespModel<>("failed", "500",
                    "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    /**
     * 重置密码
     */
    public RespModel<String> updatePasswordByReset(UserRegModel userInput) {
        if (userInput == null || StringUtils.isBlank(userInput.getUsername())
                || StringUtils.isBlank(userInput.getPassword())
                || StringUtils.isBlank(userInput.getApplicationId())
//                || StringUtils.isBlank(userInput.getCheckcodeId())
                || userInput.getUserinfo() == null
                || StringUtils.isBlank(userInput.getUserinfo().getRealname())
                || StringUtils.isBlank(userInput.getUserinfo().getDrivingsfzmhm())
//                || StringUtils.isBlank(userInput.getCheckcode())
        ) {
            RespModel<String> resp = new RespModel<String>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        // 没有短信验证码23

        if (StringUtils.isNotBlank(userInput.getCheckcodeId())) {

            // check check code is ok
            ExpiringMap<String, CheckCodeModel> map = ExpiringMapUtil.expiringMap;
            if (!map.containsKey(userInput.getCheckcodeId())) {
                RespModel<String> resp = new RespModel<>("failed", "404", "USER IS NOT EXIST", null);
                return resp;
            }
            // 1.用户填写的验证码和验证码不符；2.发送验证码的号码和用户注册的手机号码不符
            if (!(map.get(userInput.getCheckcodeId()).getCheckcode().equals(userInput.getCheckcode()))) {
                RespModel<String> resp = new RespModel<>("failed", "403", "CHECKCODE IS WRONG", null);
                return resp;
            }
            if (!map.get(userInput.getCheckcodeId()).getId().equals(userInput.getUsername())) {
                return new RespModel<String>(
                        "failed",
                        "405",
                        "THE PHONE OF RECEVIE CHECKCODE IS DIFFERENT WITH USERNAME",
                        null);
            }
        }
        try {
            User u = userDao.findOne(userInput.getUsername());
            if (u == null) {
                RespModel<String> resp = new RespModel<String>("failed", "404", "NO SUCH USER", null);
                return resp;
            }
            UserInfo ui = userInput.getUserinfo();
            // 校验身份证号码
            UserInfo userInfo = userInfoDao.selectOneByName(userInput.getUsername());
            if (!userInfo.getRealname().equals(ui.getRealname())) {
                return new RespModel<>("failed", "401", "NAME ID NOT MATCH", null);
            }
            if (!userInfo.getDrivingsfzmhm().equals(ui.getDrivingsfzmhm())) {
                return new RespModel<>("failed", "401", "NAME ID NOT MATCH", null);
            }
            if (u.getPassword().equals(DigestUtil.md5(userInput.getPassword()))) {
                return new RespModel<>("failed", "402", "PASSWORD SAME AS OLD.", null);
            }
            u.setPassword(DigestUtil.md5(userInput.getPassword()));
//            u.setLastModifyTime(new Date());
            // userDao.flush();
            userDao.updateById(u);
            //add stats
//			statsService.addStats(new Stats(userInput.getApplicationId(),userInput.getUsername(), UserBehavior.REG.toString(),""));
            RespModel<String> resp = new RespModel<String>("success", "", "", "USER RESET PASSWORD SUCCESS");
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(User reset password user is fail):", e);
            RespModel<String> resp = new RespModel<String>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    /**
     * 获取用户信息
     */
    @Override
    public RespModel<UserInfo> getInfo(String username) {
        RespModel<UserInfo> resp;
        UserInfo ui = userInfoDao.selectOneByName(username);
        if (ui != null) {
            resp = new RespModel<>("success", "", "GET USER INFO SUCCESS", ui);
            return resp;
        } else {
            resp = new RespModel<>("failed", "404", "NO SUCH USER", ui);
        }
        return resp;
    }

    @Override
    public RespModel<String> addOrUpdateInfo(String applicationId,
                                             UserInfoModel userInfoModel, String jwttoken) {
        if (StringUtils.isBlank(applicationId) || userInfoModel == null || StringUtils.isBlank(jwttoken)) {
            RespModel<String> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        try {
            // 查询appliaction,获得secret key
            Application application = applicationDao.findOne(applicationId);
            if (application == null) {
                RespModel<String> resp = new RespModel<>("failed", "405", "NO SUCH APPLICATION", null);
                return resp;
            }
            // 解析token
            byte[] secret = Base64.decodeBase64(application.getApplicationSecret());
            Map<String, Object> decodedPayload = new JWTVerifier(secret).verify(jwttoken);
            logger.debug("decodedPayload：" + decodedPayload);
            // 查询用户信息
            String username = (String) decodedPayload.get("sub");
            // 新增或更新用户消息
            UserInfo ui = userInfoDao.selectOneByName(username);
            if (ui == null) {
                ui = new UserInfo();
                ui.setUsername(username);
                ui.setApplicationId(applicationId);
                ui.setPhone(userInfoModel.getPhone());
                ui.setNickname(userInfoModel.getNickname());
                ui.setEmail(userInfoModel.getEmail());
                ui.setRealname(userInfoModel.getRealname());
                ui.setAddress(userInfoModel.getAddress());
                ui.setIcon(userInfoModel.getIcon());
                ui.setIconurl(userInfoModel.getIconurl());
                ui.setDrivingdabh(userInfoModel.getDrivingdabh());
                ui.setDrivingsfzmhm(userInfoModel.getDrivingsfzmhm());
                userInfoDao.insert(ui);
            } else {
                ui.setUsername(username);
                ui.setApplicationId(applicationId);
                ui.setPhone(userInfoModel.getPhone());
                ui.setNickname(userInfoModel.getNickname());
                ui.setEmail(userInfoModel.getEmail());
                ui.setRealname(userInfoModel.getRealname());
                ui.setAddress(userInfoModel.getAddress());
                ui.setIcon(userInfoModel.getIcon());
                ui.setIconurl(userInfoModel.getIconurl());
                ui.setDrivingdabh(userInfoModel.getDrivingdabh());
                ui.setDrivingsfzmhm(userInfoModel.getDrivingsfzmhm());
                userInfoDao.updateById(ui);
            }
            RespModel<String> resp = new RespModel<String>("success", "", "", "SUCCESSFUL");
            return resp;
        } catch (java.security.SignatureException e) {// 签名不合法
            logger.error("Signature Exception:", e);
            RespModel<String> resp = new RespModel<String>("failed", "403", "NOT AUTHORIZED", null);
            return resp;
        } catch (JWTExpiredException e) { // 签名过期
            logger.error("JWTExpired Exception:", e);
            RespModel<String> resp = new RespModel<String>("failed", "401", "TOKEN EXPIRED", null);
            return resp;
        } catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException | JWTVerifyException e) {
            logger.error("addOrUpdateInfo Exception:", e);
            RespModel<String> resp = new RespModel<String>("failed", "403", "NOT AUTHORIZED", null);
            return resp;
        } catch (Exception e) {
            logger.error("addOrUpdateInfo Exception:", e);
            RespModel<String> resp = new RespModel<String>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }

    }

    // 修改密码
    @Override
    public RespModel<String> updatePasswordByChange(ChangePasswordModel cpwmodel) {
        if (cpwmodel == null
                || StringUtils.isBlank(cpwmodel.getApplicationId())
                || StringUtils.isBlank(cpwmodel.getUsername())
                || StringUtils.isBlank(cpwmodel.getNewpassword())
                || StringUtils.isBlank(cpwmodel.getOldpassword())) {
            RespModel<String> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        try {
            User u = userDao.findOne(cpwmodel.getUsername());
            if (u == null) {
                RespModel<String> resp = new RespModel<String>("failed", "404", "NO SUCH USER", null);
                return resp;
            }
            if (!StringUtils.equals(u.getPassword(), DigestUtil.md5(cpwmodel.getOldpassword()))) {
                RespModel<String> resp = new RespModel<String>("failed", "403", "USER PASSWORD ERROR", null);
                return resp;
            }
            u.setPassword(DigestUtil.md5(cpwmodel.getNewpassword()));
            // userDao.flush();
            userDao.updateById(u);
            RespModel<String> resp = new RespModel<String>("success", "", "", "USER CHANGE PASSWORD SUCCESS");
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(User reset password user is fail):", e);
            RespModel<String> resp = new RespModel<String>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    /**
     * Icon上传
     *
     * @return
     */
    public RespModel<HashMap<String, Object>> addIcon(String username, String icon_url) {

        UserInfo ui = userInfoDao.selectOneByName(username);
        if (ui == null) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername(username);
            userInfo.setIconurl(icon_url);
            userInfoDao.insert(userInfo);
        } else {
            ui.setIconurl(icon_url);
            userInfoDao.updateById(ui);
        }
        HashMap<String, Object> res = new HashMap<>();
        res.put("icon_url", icon_url);
        RespModel<HashMap<String, Object>> resp = new RespModel<>("success", "", "", res);
        return resp;

    }

    /**
     * 检查一个用户是否已注册
     *
     * @return
     */
    @Override
    public RespModel<User> userExist(UserExistModel user) {
        if (StringUtils.isBlank(user.getApplicationId()) || StringUtils.isBlank(user.getUsername())) {
            RespModel<User> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        try {
            User u = userDao.findOne(user.getUsername());
            user.setExist(u != null);  //设置用户是否存在值 true false
            RespModel<User> resp = new RespModel("success", "", "", user);
            return resp;
        } catch (Exception e) {
            logger.error("error:", e);
            RespModel<User> resp = new RespModel<>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    @Override
    public RespModel<String> addNewUser(UserRegModel userInput) {
        if (userInput == null || StringUtils.isBlank(userInput.getUsername())
                || StringUtils.isBlank(userInput.getPassword())
                || userInput.getUserinfo() == null
                || StringUtils.isBlank(userInput.getUserinfo().getRealname())
                || StringUtils.isBlank(userInput.getUserinfo().getDrivingsfzmhm())
                || StringUtils.isBlank(userInput.getApplicationId())) {
            RespModel<String> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        User user = new User();
        user.setApplicationId(userInput.getApplicationId());
        user.setUsername(userInput.getUsername());
        user.setPassword(DigestUtil.md5(userInput.getPassword()));
//        user.setCreateDate(new Date());
        try {
            User u = userDao.findOne(userInput.getUsername());
            if (u != null) {
                RespModel<String> resp = new RespModel<>("failed", "400", "USER ALREADY EXIST", null);
                return resp;
            }
            UserInfo ui = userInput.getUserinfo();
            // 校验身份证号码
            if (!dataInfoQueryService.checkNameAndIDCard(ui.getRealname(), ui.getDrivingsfzmhm())) {
                return new RespModel<>("failed", "401", "NAME ID NOT MATCH", null);
            }
            userDao.insert(user);
            //ADD USERINFO
            if (ui != null) {
                ui.setUsername(userInput.getUsername());
                ui.setApplicationId(userInput.getApplicationId());
                userInfoDao.insert(ui);
            }
            //add stats
//			statsService.addStats(new Stats(userInput.getApplicationId(),userInput.getUsername(), UserBehavior.REG.toString(),""));
            RespModel<String> resp = new RespModel<String>("success", "", "USER REG SUCCESS", null);
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(add user is fail):", e);
            RespModel<String> resp = new RespModel<String>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }


    /**
     * 绑定微信
     *
     * @return
     */
    public RespModel<String> updateBoundWechat(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        String applicationId = jsonObject.getString("applicationId");    //应用ID
        String userName = jsonObject.getString("userName");            //用户ID
        String wxOpenId = jsonObject.getString("wxOpenId");    //微信openId
        String wxUnionId = jsonObject.getString("wxUnionId");    //微信unionId
        String nickName = jsonObject.getString("nickName");        //微信昵称
        String wxAvatar = jsonObject.getString("wxAvatar");        //微信头像

        if (StringUtils.isBlank(applicationId) || StringUtils.isBlank(userName)
                || StringUtils.isBlank(wxOpenId) || StringUtils.isBlank(wxUnionId)) {
            RespModel<String> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }

        //获取用户信息，判断applicationId是否正确
        User user = userDao.findOne(userName);
        if (user.getApplicationId().equals(applicationId)) {
            user.setId(user.getId());
            user.setWxOpenId(wxOpenId);
            user.setWxUnionId(wxUnionId);
            user.setNickName(nickName);
            user.setWxAvatar(wxAvatar);
//            user.setLastModifyTime(new Date());
        } else {
            RespModel<String> resp = new RespModel<>("failed", "406", "APPLICATIONID IS NOT CORRECT", null);
            return resp;
        }

        try {
            userDao.updateById(user);
            RespModel<String> resp = new RespModel<>("success", "", "", "USER BOUND SUCCESS");
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(User bound wechat is fail):", e);
            RespModel<String> resp = new RespModel<>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    /**
     * 微信解绑
     *
     * @return
     */
    public RespModel<String> updateUnBoundWechat(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        String applicationId = jsonObject.getString("applicationId");    //应用ID
        String userName = jsonObject.getString("userName");                    //用户ID
        String checkCodeId = jsonObject.getString("checkCodeId");        //保存验证码、手机号信息的对象key
        String checkCode = jsonObject.getString("checkCode");            //验证码

        //验证参数完整性
        if (StringUtils.isBlank(applicationId) || StringUtils.isBlank(userName)
                || StringUtils.isBlank(checkCodeId) || StringUtils.isBlank(checkCode)) {
            RespModel<String> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        /***/
        //验证是否存在此验证码
        ExpiringMap<String, CheckCodeModel> map = ExpiringMapUtil.expiringMap;
        if (!map.containsKey(checkCodeId)) {
            RespModel<String> resp = new RespModel<>("failed", "404", "CHECKCODE IS OUTDATED", null);
            return resp;
        }
        // 1.用户填写的验证码和验证码不符；2.发送验证码的号码和用户注册的手机号码不符
        if (!map.get(checkCodeId).getCheckcode().equals(checkCode)) {
            RespModel<String> resp = new RespModel<>("failed", "403", "CHECKCODE IS WRONG", null);
            return resp;
        }

        //获取用户信息，判断applicationId是否正确
        User user = userDao.findOne(userName);
        if (user.getApplicationId().equals(applicationId)) {
            user.setId(user.getId());
            user.setWxOpenId("");
            user.setWxUnionId("");
            user.setNickName("");
            user.setWxAvatar("");
//            user.setLastModifyTime(new Date());
        } else {
            RespModel<String> resp = new RespModel<>("failed", "406", "APPLICATIONID IS NOT CORRECT", null);
            return resp;
        }

        try {
            userDao.updateById(user);
            RespModel<String> resp = new RespModel<>("success", "", "", "USER BOUND SUCCESS");
            return resp;
        } catch (Exception e) {
            logger.error("SYSTEM_IS_EXCEPTION(User bound wechat is fail):", e);
            RespModel<String> resp = new RespModel<>("failed", "500", "INTERNAL SERVER ERROR", null);
            return resp;
        }
    }

    /**
     * 获取绑定微信信息
     *
     * @return
     */
    public RespModel<User> getBoundInfo(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        String applicationId = jsonObject.getString("applicationId");    //应用ID
        String userName = jsonObject.getString("userName");            //userName

        if (StringUtils.isBlank(applicationId) || StringUtils.isBlank(userName)) {
            RespModel<User> resp = new RespModel<>("failed", "406", "PARAM IS MISS", null);
            return resp;
        }

        //获取用户信息，判断applicationId是否正确
        User user = userDao.findOne(userName);
        if (user == null) {
            RespModel<User> resp = new RespModel<>("failed", "405", "NO SUCH USER", null);
            return resp;
        }
        if (!applicationId.equals(user.getApplicationId())) {
            RespModel<User> resp = new RespModel<>("failed", "406", "APPLICATIONID IS NOT CORRECT", null);
            return resp;
        } else {
            RespModel<User> resp = new RespModel<>("success", "", "", user);
            return resp;
        }
    }

    /**
     * handlerinterceptor 查询用户信息
     *
     * @param userID
     * @return
     */
    public User selectById(Long userID) {
        return userDao.selectById(userID);
    }

    /**
     * 用户登录--生成token
     *
     * @param tokenValidateModel
     * @return
     */
    public RespModel<TokenModel> login(TokenGeneratorInputModel tokenValidateModel) {
        // 校验参数是否为空
        if (tokenValidateModel == null || StringUtils.isBlank(tokenValidateModel.getApplicationId())
                || StringUtils.isBlank(tokenValidateModel.getConnection())
                || StringUtils.isBlank(tokenValidateModel.getIdentity())) {
            RespModel<TokenModel> resp = new RespModel("failed", "406", "PARAM IS MISS", null);
            return resp;
        }
        // 查询application是否存在
        Application application = applicationDao.findOne(tokenValidateModel.getApplicationId());
        if (application == null) {
            RespModel<TokenModel> resp = new RespModel("failed", "405", "NO SUCH APPLICATION", null);
            return resp;
        }

        // package this as identity provider
        String username = "";
        switch (tokenValidateModel.getConnection()) {
            case "dbpassword":
                User user = JSON.parseObject(tokenValidateModel.getIdentity(), User.class);
                User u = userDao.findOne(user.getUsername());
                if (u == null || !u.getPassword().equals(DigestUtil.md5(user.getPassword()))) {
                    return new RespModel("failed", "403", "IDENTITY NOT CORRECT", null);
                }
                username = u.getUsername();
                break;
            case "sms":
                RespModel<String> identiyReturn = smsIdentityProvider(tokenValidateModel.getIdentity());
                if (!"success".equals((identiyReturn.getStatus()))) {
                    return new RespModel(identiyReturn.getStatus(), identiyReturn.getErrorcode(), identiyReturn.getReason(), null);
                }
                username = identiyReturn.getResult();
                break;
            default:
                RespModel<TokenModel> resp = new RespModel("failed", "501",
                        "CONNECTION TYPE " + tokenValidateModel.getConnection() + " IS NOT IMPLEMENTED", null);
                return resp;
        }
        // 生成token
        String token = genToken(username, application);
        // add stats
//        statsService.addStats(new Stats(application.getApplicationId(), (String) identiyReturn.getResult(),
//                UserBehavior.LOGON.toString(), ""));
        // 成功返回token
        RespModel<TokenModel> resp = new RespModel("success", "", "", new TokenModel(tokenValidateModel.getApplicationId(), token));
        return resp;
    }

    /**
     * 根据用户名获取消息
     *
     * @param userid
     * @return
     */
    @Override
    public List<MessageEntity> getMyMessage(String userid) {
        EntityWrapper entityWrapper = new EntityWrapper();
        entityWrapper.isNull("username")
                .or().eq("username", userid)
                .or().eq("username", "全部设备")
//                .andNew().eq("type", "0")//0表示普通消息，1表示单挑推送，2表示推送全部设备
                .orderBy("createdate", false);
        return messageEntityDao.selectList(entityWrapper);
    }

    /**
     * 读取消息
     *
     * @param messageId
     * @return
     */
    @Override
    public int read(String messageId) {
        MessageEntity entity = messageEntityDao.selectById(messageId);
        //设置状态为已读
        entity.setReadstate(1);
        return messageEntityDao.updateById(entity);
    }

    /**
     * 生成token
     *
     * @param username
     * @param application
     * @return
     */
    private String genToken(String username, Application application) {
        byte[] secret = Base64.decodeBase64(application.getApplicationSecret());
        JWTSigner signer = new JWTSigner(secret);
        HashMap<String, Object> claims = new HashMap<String, Object>();
        claims.put("iss", "ehualu-auth"); // 发证机关
        claims.put("sub", username); // 用户名
        // TODO 过期时间有待在定义
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime expiredate = localDateTime.plusDays(30);
        claims.put("exp", expiredate.toInstant(ZoneOffset.of("+8")).toEpochMilli() / 1000); // 过期时间
        claims.put("iat", localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()); // 生成时间
        claims.put("aud", application.getApplicationId()); // application id
        return signer.sign(claims);
    }

    /**
     * 手机短信方式登陆
     *
     * @param identity
     * @return
     */
    public RespModel<String> smsIdentityProvider(String identity) {

        VerifyCheckCodeInputModel checkcodeInput = JSONObject.parseObject(identity, VerifyCheckCodeInputModel.class);
        // check check code is ok
        ExpiringMap<String, CheckCodeModel> map = ExpiringMapUtil.expiringMap;
        if (!map.containsKey(checkcodeInput.getId())) {
            RespModel<String> resp = new RespModel("failed", "404", "CHECKCODE IS OUTDATED", null);
            return resp;
        }
        // 1.用户填写的验证码和验证码不符；2.发送验证码的号码和用户注册的手机号码不符
        if (!map.get(checkcodeInput.getId()).getCheckcode().equals(checkcodeInput.getCheckcode())) {
            RespModel<String> resp = new RespModel("failed", "403", "CHECKCODE IS WRONG", null);
            return resp;
        }
        if (!map.get(checkcodeInput.getId()).getId().equals(checkcodeInput.getPhone())) {
            return new RespModel("failed", "405", "THE PHONE OF RECEVIE CHECKCODE IS DIFFERENT WITH USERNAME", null);
        }
        return new RespModel("success", "", "", checkcodeInput.getPhone());
    }

}